package com.dropdb.demo.service.impl;

import com.dropdb.demo.bean.*;
import com.dropdb.demo.bean.bo.CheckOutDataBO;
import com.dropdb.demo.bean.bo.GoodsCommentBO;
import com.dropdb.demo.bean.vo.*;
import com.dropdb.demo.mapper.*;
import com.dropdb.demo.service.WxCartService;
import com.dropdb.demo.service.WxOrderService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author qugr
 * @create 2020-06-30 18:34
 */
@Service
public class WxOrderServiceImpl implements WxOrderService {

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    OrderGoodsMapper orderGoodsMapper;

    @Autowired
    GoodsProductMapper goodsProductMapper;

    @Autowired
    CommentMapper commentMapper;

    @Autowired
    CouponUserMapper couponUserMapper;

    @Autowired
    WxCartService wxCartService;

    @Autowired
    CartMapper cartMapper;

    /**
     * 订单按状态分页显示
     * @param showType 订单状态分类
     * @param page
     * @param size
     * @param userId
     * @return
     */
    @Override
    public BaseRespVO queryOrders(Integer showType, Integer page, Integer size, Integer userId) {

        //获取订单列表
        OrderExample orderExample = new OrderExample();
        OrderExample.Criteria criteria = orderExample.createCriteria();
        //获取状态码
        List orderStatus = OrderStatus.getOrderStatus(showType);
        if (orderStatus != null) {
            criteria.andOrderStatusIn(orderStatus);
        }
        if (showType == 4) {
            criteria.andCommentsNotEqualTo((short) 0);
        }
        //根据userId、未删除的订单、和更新时间的降序查找订单
        criteria.andUserIdEqualTo(userId).andDeletedEqualTo(false);
        orderExample.setOrderByClause("update_time desc");
        //分页显示
        PageHelper.startPage(page,size);
        List<UserOrderListVO> userOrderListVOS = orderMapper.selectOrderInfoByExample(orderExample);

        //获取订单数量
        Long total = new PageInfo<>(userOrderListVOS).getTotal();

        //定义map用于返回前台的json数据
        Map userOrderData = new HashMap();
        userOrderData.put("count",total);
        //根据订单数量 得到显示页数。 0 条订单， 显示 0 页
        userOrderData.put("totalPages", total / size);
        if (total > 0 ) {
            //订单 > 0 且数量不是整数，页数 +1
            if (total % size > 0) {
                userOrderData.put("totalPages", total / size + 1);
            }
            for (UserOrderListVO userOrderListVO : userOrderListVOS) {
                short status = userOrderListVO.getOrderStatus();
                //给HandleOption属性赋值
                userOrderListVO.setHandleOption(HandleOption.getInstance(status));
                //给orderStatusText属性赋值
                userOrderListVO.setOrderStatusText(OrderStatus.getOrderStatusText(status));
            }
        }
        userOrderData.put("data",userOrderListVOS);

        return BaseRespVO.ok(userOrderData);
    }

    /**
     * 订单详情页
     * @param orderId
     * @return
     */
    @Override
    public BaseRespVO queryOrderInfo(Integer orderId) {

        //获取订单详细信息
        UserOrderInfoVO userOrderInfoVO = orderMapper.selectOrderInfoByPrimaryKey(orderId);
        if (userOrderInfoVO == null) {
            return BaseRespVO.error(700, "订单不存在");
        }
        //给HandleOption属性赋值
        short status = userOrderInfoVO.getOrderStatus();
        userOrderInfoVO.setHandleOption(HandleOption.getInstance(status));
        //给orderStatusText属性赋值
        userOrderInfoVO.setOrderStatusText(OrderStatus.getOrderStatusText(status));

        //获取订单的商品列表
        OrderGoodsExample orderGoodsExample = new OrderGoodsExample();
        orderGoodsExample.createCriteria().andOrderIdEqualTo(orderId);
        List<OrderGoods> orderGoods = orderGoodsMapper.selectByExample(orderGoodsExample);

        Map userOrderInfoData = new HashMap();
        userOrderInfoData.put("orderGoods",orderGoods);
        userOrderInfoData.put("orderInfo",userOrderInfoVO);

        return BaseRespVO.ok(userOrderInfoData);
    }

    /**
     * 取消订单，更新 订单状态和更新时间
     * @param orderId
     * @param status
     * @return
     */
    @Override
    @Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED)
    public BaseRespVO cancelOrder(Integer orderId, short status) {

        //更新订单已取消状态和取消时间
        Order order = new Order();
        order.setId(orderId);
        order.setOrderStatus(status);
        order.setUpdateTime(new Date());
        updatebOrder(order);

        //获取订单商品列表
        OrderGoodsExample orderGoodsExample = new OrderGoodsExample();
        orderGoodsExample.createCriteria().andOrderIdEqualTo(orderId);
        List<OrderGoods> orderGoods = orderGoodsMapper.selectByExample(orderGoodsExample);

        //取消订单后更新库存
        for (OrderGoods orderGood : orderGoods) {

            //获取订单中商品的库存
            GoodsProductExample goodsProductExample = new GoodsProductExample();
            goodsProductExample.createCriteria().andIdEqualTo(orderGood.getProductId());
            int totalNum = goodsProductMapper.selectProductNumByExample(goodsProductExample);

            //取消订单后，商品的库存为 前库存 + 订单中商品的数量
            GoodsProduct goodsProduct = new GoodsProduct();
            goodsProduct.setNumber((orderGood.getNumber() + totalNum) + "");
            goodsProductMapper.updateByExampleSelective(goodsProduct,goodsProductExample);
        }

        //取消订单须返还优惠券，根据orderId将优惠券置为未使用
        CouponUser couponUser = new CouponUser();
        couponUser.setStatus((short) 0);
        couponUser.setOrderId(null);
        CouponUserExample couponUserExample = new CouponUserExample();
        couponUserExample.createCriteria().andOrderIdEqualTo(orderId);
        couponUserMapper.updateByExampleSelective(couponUser,couponUserExample);

        return BaseRespVO.ok();
    }

    /**
     * 申请退款 会取消订单。直接调用取消订单的方法
     * @param orderId
     * @param status
     * @return
     */
    @Override
    public BaseRespVO refund(Integer orderId, short status) {
        return cancelOrder(orderId,status);
    }

    /**
     * 确认收货 更新订单状态和时间
     * @param orderId
     * @param status
     * @return
     */
    @Override
    public BaseRespVO confirm(Integer orderId, short status) {

        Order order = new Order();
        order.setId(orderId);
        order.setOrderStatus(status);
        order.setUpdateTime(new Date());
        order.setConfirmTime(new Date());

        //获取orderGoods的个数
        OrderGoodsExample orderGoodsExample = new OrderGoodsExample();
        orderGoodsExample.createCriteria().andOrderIdEqualTo(orderId).andCommentEqualTo(0);
        long count = orderGoodsMapper.countByExample(orderGoodsExample);
        //确认收货后，更新订单的未评论商品个数
        order.setComments((short) count);
        updatebOrder(order);

        return BaseRespVO.ok();
    }

    /**
     * 评价商品页面的商品信息
     * @param orderId
     * @param goodsId
     * @return
     */
    @Override
    public BaseRespVO queryOrderGoodsInfo(Integer orderId, Integer goodsId) {

        OrderGoodsExample orderGoodsExample = new OrderGoodsExample();
        orderGoodsExample.createCriteria().andOrderIdEqualTo(orderId).andGoodsIdEqualTo(goodsId);
        List<OrderGoods> orderGoods = orderGoodsMapper.selectByExample(orderGoodsExample);

        return BaseRespVO.ok(orderGoods.get(0));
    }

    /**
     * 逻辑删除订单
     * @param orderId
     * @return
     */
    @Override
    @Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED)
    public BaseRespVO deleteOrder(Integer orderId) {

        //删除订单
        Order order = new Order();
        order.setId(orderId);
        order.setDeleted(true);
        order.setUpdateTime(new Date());
        updatebOrder(order);

        //异常测试
        //int i = 10 / 0;

        //删除订单商品列表
        OrderGoods orderGoods = new OrderGoods();
        orderGoods.setDeleted(true);
        OrderGoodsExample orderGoodsExample = new OrderGoodsExample();
        orderGoodsExample.createCriteria().andOrderIdEqualTo(orderId);
        orderGoodsMapper.updateByExampleSelective(orderGoods,orderGoodsExample);

        return BaseRespVO.ok();
    }

    @Override
    @Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED)
    public BaseRespVO createGoodsComment(GoodsCommentBO goodsCommentBO) {

        //评价信息
        Comment comment = new Comment();
        //商品评价的valueId为goodsId
        comment.setValueId(orderGoodsMapper.selectByPrimaryKey(goodsCommentBO.getOrderGoodsId()).getGoodsId());
        comment.setContent(goodsCommentBO.getContent());
        comment.setUserId(goodsCommentBO.getUserId());
        comment.setHasPicture(goodsCommentBO.getHasPicture());
        comment.setPicUrls(goodsCommentBO.getPicUrls());
        comment.setStar(goodsCommentBO.getStar());
        comment.setAddTime(new Date());
        comment.setUpdateTime(new Date());
        //将携带数据的comment插入评价表
        commentMapper.insertSelective(comment);

        //更新订单商品为已评论状态
        OrderGoods orderGoods = orderGoodsMapper.selectByPrimaryKey(goodsCommentBO.getOrderGoodsId());
        orderGoods.setComment(comment.getId());
        orderGoods.setUpdateTime(new Date());
        orderGoodsMapper.updateByPrimaryKeySelective(orderGoods);

        //评论后减少订单未评论数量
        Order order = orderMapper.selectByPrimaryKey(orderGoods.getOrderId());
        short comments = order.getComments();
        if (comments > 0) {
            comments--;
        }
        order.setComments(comments);
        updatebOrder(order);


        return BaseRespVO.ok();
    }

    /**
     * 支付（伪）
     * @param orderId
     * @param status
     * @return
     */
    @Override
    public BaseRespVO prepayOrder(Integer orderId, short status) {

        Order order = new Order();
        order.setId(orderId);
        order.setOrderStatus(status);
        order.setUpdateTime(new Date());
        order.setPayTime(new Date());
        updatebOrder(order);
        //支付成功不跳转，做一个伪跳转
        try {
            int i = 10 / 0;
        } catch (Exception e) {
            return BaseRespVO.error(400,"支付成功，伪跳转");
        }

        return BaseRespVO.ok();
    }

    /**
     * 下单
     * @param map 封装请求参数
     * @param userId
     * @return
     */
    @Override
    @Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED)
    public BaseRespVO submitOrder(Map<String, Object> map, int userId) {

        //根据请求数据获取下单信息
        int addressId = (int) map.get("addressId");
        int couponId = (int) map.get("couponId");
        int cartId = (int) map.get("cartId");
        CheckOutDataBO checkout = wxCartService.checkout(userId, cartId, addressId, couponId, 0);

        //获取当前时间
        Date date = new Date();
        String time = new SimpleDateFormat("yyyyMMddHHmmss").format(date);
        //根据当前时间+一位随机数 生成订单编号
        String orderSn = time + "" + (int) (Math.random() * 100 % 10);

        Order order = new Order();
        order.setUserId(userId);
        order.setOrderSn(orderSn);
        order.setOrderStatus((short) 101);
        order.setConsignee(checkout.getCheckedAddress().getName());
        order.setMobile(checkout.getCheckedAddress().getMobile());
        order.setAddress(checkout.getCheckedAddress().getAddress());
        order.setMessage((String) map.get("message"));
        order.setGoodsPrice(checkout.getGoodsTotalPrice());
        order.setFreightPrice(checkout.getFreightPrice());
        order.setCouponPrice(checkout.getCouponPrice());
        order.setIntegralPrice(BigDecimal.valueOf(0.00));
        order.setGrouponPrice(BigDecimal.valueOf(0.00));
        order.setOrderPrice(checkout.getOrderTotalPrice());
        if (order.getOrderPrice() == null) {
            order.setOrderPrice(checkout.getGoodsTotalPrice());
        }
        order.setActualPrice(checkout.getActualPrice());
        order.setAddTime(date);
        order.setUpdateTime(date);
        //写入订单表
        orderMapper.insertSelective(order);
        //获得自增的订单id
        int orderId = order.getId();

        List<Cart> carts = checkout.getCheckedGoodsList();
        for (Cart cart : carts) {
            //将订单商品写入数据库
            OrderGoods orderGood = new OrderGoods();
            orderGood.setOrderId(orderId);
            orderGood.setGoodsId(cart.getGoodsId());
            orderGood.setGoodsName(cart.getGoodsName());
            orderGood.setGoodsSn(cart.getGoodsSn());
            orderGood.setProductId(cart.getProductId());
            orderGood.setNumber(cart.getNumber());
            orderGood.setPrice(cart.getPrice());
            orderGood.setComment(0);
            String specifications = cart.getSpecifications();
            orderGood.setSpecifications(specifications.substring(2,specifications.length() - 2).split("\",\""));

            orderGood.setPicUrl(cart.getPicUrl());
            orderGood.setAddTime(date);
            orderGood.setUpdateTime(date);
            orderGoodsMapper.insertSelective(orderGood);

            //下单后更新商品库存
            GoodsProductExample goodsProductExample = new GoodsProductExample();
            goodsProductExample.createCriteria().andIdEqualTo(orderGood.getProductId());

            //获取订单中商品的库存
            int totalNum = goodsProductMapper.selectProductNumByExample(goodsProductExample);
            if (totalNum - orderGood.getNumber() < 0) {
                 int i = 10 / 0;
//                return BaseRespVO.error(711,"当前库存不足，下单失败");
            }
            GoodsProduct goodsProduct = new GoodsProduct();
            //下单后，商品的库存为 前库存 - 订单中商品的数量
            goodsProduct.setNumber((totalNum - orderGood.getNumber()) + "");
            //更新商品的库存
            goodsProductMapper.updateByExampleSelective(goodsProduct,goodsProductExample);

            //删除购物车
            cart.setDeleted(true);
            cartMapper.updateByPrimaryKey(cart);

        }

        //下单后更新优惠券使用状态
        if (couponId != 0 && couponId != -1) {
            CouponUser couponUser = new CouponUser();
            //将优惠券置为已使用
            couponUser.setStatus((short) 1);
            couponUser.setOrderId(orderId);
            couponUser.setUsedTime(date);
            CouponUserExample couponUserExample = new CouponUserExample();
            couponUserExample.createCriteria().andUserIdEqualTo(userId).andCouponIdEqualTo(couponId);
            //根据couponId、userId改变优惠券状态
            couponUserMapper.updateByExampleSelective(couponUser,couponUserExample);
        }

        HashMap<String, Integer> respMap = new HashMap<>();
        respMap.put("orderId",orderId);
        return BaseRespVO.ok(respMap);
    }

    /**
     * 更新订单数据的方法
     * @param order
     * @return
     */
    public int updatebOrder(Order order) {

        return orderMapper.updateByPrimaryKeySelective(order);
    }

}
